use std::ops::Sub;

#[derive(Debug, Clone, Copy)]
struct Date {
    year: usize,
    month: usize,
    day: usize,
}

impl Date {
    fn to_days_ref(&self) -> i32 {
        let mut days = 0;
        for year in START_YEAR..self.year {
            days += if is_leap(year) { 366 } else { 365 };
        }
        days += self.to_days();
        days as i32
    }

    fn to_days(&self) -> i32 {
        let mut days = 0;
        for month in 0..(self.month - 1) {
            days += MONTHS[month];
        }
        days += self.day;
        if is_leap(self.year) && self.month > 2 {
            days += 1;
        }
        days as i32
    }

    fn cal_endof_year(&self) -> i32 {
        let days = if is_leap(self.year) { 366 } else { 365 };
        days - self.to_days()
    }

    fn cal_iso_weeks(&self) -> i32 {
        // 1月4日所在的星期为第一周
        // 2000年1月1日是星期六
        let first_week = Date {
            year: self.year,
            month: 1,
            day: 4,
        };
        let mut first_days = first_week.to_days_ref();
        let index = (first_days + 5) % 7;
        first_days = first_days - index + 1;

        let next_first_week = Date {
            year: self.year + 1,
            month: 1,
            day: 4,
        };
        let next_first_days = next_first_week.to_days_ref();
        let mut next_index = (next_first_days + 5) % 7;
        if next_index == 0 {
            next_index = 7;
        }
        let next_first_days = next_first_days - next_index + 1;

        let days = self.to_days_ref();
        if days >= next_first_days {
            (days - next_first_days) / 7 + 1
        } else {
            (days - first_days) / 7 + 1
        }
    }

    fn cal_endof_newyear(&self) -> i32 {
        let new_year = get_date(NEW_YEAR[self.year - START_YEAR]);
        let next_new_year = get_date(NEW_YEAR[self.year - START_YEAR + 1]);
        if (new_year - *self) > 0 {
            new_year - *self - 1
        } else {
            next_new_year - *self - 1
        }

    }
}

impl Sub for Date {
    type Output = i32;

    fn sub(self, rhs: Self) -> Self::Output {
        self.to_days_ref() - rhs.to_days_ref()
    }
}

// 从2000年开始，到2030年结束
const START_YEAR: usize = 2000;
const NEW_YEAR: [&str; 31] = [
    "2000-02-05", "2001-01-24", "2002-02-12", "2003-02-01", "2004-01-22",
    "2005-02-09", "2006-01-29", "2007-02-18", "2008-02-07", "2009-01-26",
    "2010-02-14", "2011-02-03", "2012-01-23", "2013-02-10", "2014-01-31",
    "2015-02-19", "2016-02-08", "2017-01-28", "2018-02-16", "2019-02-05",
    "2020-01-25", "2021-02-12", "2022-02-01", "2023-01-22", "2024-02-10",
    "2025-01-29", "2026-02-17", "2027-02-06", "2028-01-26", "2029-02-13",
    "2030-02-03",
];


const MONTHS: [usize; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

fn is_leap(year: usize) -> bool {
    year % 4 == 0 && year % 100 != 0 || year % 400 == 0
}

fn get_date(date: &str) -> Date {
    let mut iter = date.split('-');
    Date {
        year: iter.next().unwrap().parse().unwrap(),
        month: iter.next().unwrap().parse().unwrap(),
        day: iter.next().unwrap().parse().unwrap(),
    }
}


pub fn time_info(time: &str) -> String {
    let date = get_date(time);
    println!("{:?}", date);
    let weeks = date.cal_iso_weeks();
    let endof_year = date.cal_endof_year();
    let endof_newyear = date.cal_endof_newyear();
    println!("{},{},{}", weeks, endof_year, endof_newyear);
    format!("{},{},{}", weeks, endof_year, endof_newyear)
}
